#pragma once
#include <functional>

class Defer {
public:
    template <typename Func, typename ...Args>
    Defer(Func &&f, Args &&...args)
        :_f(std::bind(std::forward<Func>(f), std::forward<Args>(args)...))
    {   
    }   

    ~Defer()
    {   
        _f();
    }   
private:
    std::function<void()> _f; 
};

#define LIKE_GO

#ifdef LIKE_GO
#define defer_counter(obj_counter, code) Defer defer_obj ## obj_counter([&]{ \
        code; \
        })
#define defer_mid(obj_counter, code) defer_counter(obj_counter, code)
#define simple_defer(code) defer_mid(__COUNTER__, code)
#else
#define defer_counter(obj_counter, func, args...) Defer defer_obj ## obj_counter(func, ## args)
#define defer_mid(obj_counter, func, args...) defer_counter(obj_counter, func, ## args)
#define simple_defer(func, args...) defer_mid(__COUNTER__, func, ## args)
#endif
